package com.shelpe.services.algorithm.autoDrive;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.shelpe.services.algorithm.client.LexiconClient.RecommendWordDto;
import com.shelpe.services.algorithm.autoDrive.MobileRecommendWordFilter.AutoWordDto;
import com.shelpe.services.algorithm.client.SinbadClient;
import com.shelpe.services.algorithm.client.SinbadClient.HandlingKeyword;
import com.shelpe.services.algorithm.configuration.MobileQscoreProperties;
import com.shelpe.services.algorithm.entity.jpa.Adgroup;
import com.shelpe.services.algorithm.entity.jpa.AutoProductQueue;
import com.shelpe.services.algorithm.entity.jpa.Campaign;
import com.shelpe.services.algorithm.entity.jpa.UserLevelReport;
import com.shelpe.services.algorithm.repository.jpa.CampaignRepository;
import com.shelpe.services.algorithm.repository.jpa.UserLevelReportRepository;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class LowBudgetMobileRecommendWordFilter extends MobileRecommendWordFilter {

	@Autowired
	private CampaignRepository campaignRepository;
	@Autowired
	private UserLevelReportRepository userLevelReportRepository;
	@Autowired
	private MobileQscoreProperties mobileQscoreProperties;

	@Override
	public boolean support(Adgroup adgroup, AutoProductQueue queue) {
		boolean isMobile = super.support(adgroup, queue);
		Campaign campaign = this.campaignRepository.findOne(adgroup.getCampaignID());

		boolean support = isMobile && ((campaign == null) || (campaign != null && campaign.getBudget() <= 70));
		if (support) {
			log.debug("low budget mobile recommend filter: {}", adgroup);
		}
		return support;
	}

	@Override
	public List<HandlingKeyword> filter(List<RecommendWordDto> recommends, AutoProductQueue queue, Adgroup adgroup) {
		SortRes res = this.sort(recommends);
		List<AutoWordDto> words = res.getWords();

		UserLevelReport report = this.userLevelReportRepository.findFirstByUserIDOrderByDateDesc(queue.getUserID());
		boolean hasUserLevelCpc = (report != null && report.getCpc() != null && report.getCpc().floatValue() > 0);

		List<SinbadClient.HandlingKeyword> handlingWords = new ArrayList<SinbadClient.HandlingKeyword>();
		for (AutoWordDto word : words) {
			log.debug("check word: {}", word);
			SinbadClient.HandlingKeyword keyword = this.toKeyword(word, adgroup.getLimit() / 5, adgroup.getLimit());
			if (word.getRecomend().getClickRatio() > 0.01 && word.getRecomend().getClickCoverage() >= 0.01
					&& word.getRecomend().getImpression() > 100 && word.getRecomend().getWord().length() > 2
					&& (!hasUserLevelCpc || (hasUserLevelCpc
							&& word.getRecomend().getAveragePrice() < (report.getCpc().floatValue() * 2.5)))
					&& (keyword.getMaxPrice() >= 5 || keyword.getMaxMobilePrice() >= 5)
					&& word.getRecomend().isCenteral()) {
				handlingWords.add(keyword);
			} else {
				log.debug("not add as keyword: {}", word);
			}
		}
		return handlingWords;
	}

	@Override
	protected float calcScore(AutoWordDto word, AutoWordDto maxWord) {
		float score = (((float) word.getRecomend().getClickRatio()) / maxWord.getCtr()) * 60;
		score = score + (((float) word.getRecomend().getImpression()) / maxWord.getPv()) * 20;
		score = score + (((float) word.getRecomend().getClickCoverage()) / maxWord.getCoverage()) * 20;
		return score;
	}

	@Override
	protected MobileQscoreProperties getMobileQscoreProperties() {
		return this.mobileQscoreProperties;
	}

}
